package com.zhijian.medical.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.zhijian.entity.PageVo;
import com.zhijian.medical.dao.local.RoutineQcMapper;
import com.zhijian.medical.entity.po.*;
import com.zhijian.medical.entity.vo.request.*;
import com.zhijian.medical.entity.vo.response.*;
import com.zhijian.medical.enums.FileTypeEnum;
import com.zhijian.medical.enums.PatientEnums;
import com.zhijian.medical.enums.RoutineHistoryEnum;
import com.zhijian.medical.enums.RoutinePathologySampleStepEnum;
import com.zhijian.medical.holder.CurrentUserHolder;
import com.zhijian.medical.service.*;
import com.zhijian.medical.util.AssertUtil;
import com.zhijian.util.page.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import cn.hutool.core.collection.CollectionUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * 常规病理-取材业务处理层
 * 
 * @author auto
 * @version: 1.0
 * @date 2024-07-24 19:18:37
 */
@Slf4j
@Service
public class RoutineQcServiceImpl implements RoutineQcService {

	@Autowired
    private RoutineQcMapper mapper;

    @Autowired
    private FileService fileService;

    @Autowired
    private RoutineSingleSampleService singleSampleService;

    @Autowired
    private RoutineStepService stepService;

    @Autowired
    private RoutineStepRecordService stepRecordService;

    @Autowired
    private RoutineSampleService sampleService;

    @Autowired
    private RoutinePatientService patientService;
    @Autowired
    private RoutinePatientRegistService registService;

    @Override
    public RoutineQc selectById(Long id) {
        return mapper.selectByPrimaryKey(id);
    }

    @Override
    public RoutineQcVo selectVoById(Long id) {
        return mapper.selectVoById(id);
    }

    @Override
    public RoutineQcVo selectVoByNums(String nums) {
        RoutineQcVo routineQcVo = mapper.selectOne(RoutineQcSearchVo.builder().conventionPathologyNumber(nums).build());
        if (Objects.isNull(routineQcVo)) {
            return null;
        }
        // 照片
        routineQcVo.setPhotoLists(fileService.selectList(FileSearchVo.builder()
                        .dataId(routineQcVo.getId())
                        .type(FileTypeEnum.QC_BIG_PHOTO.getCode().byteValue())
                        .build()));
        // 录音
        routineQcVo.setVoiceLists(fileService.selectList(FileSearchVo.builder()
                .dataId(routineQcVo.getId())
                .type(FileTypeEnum.QC_BIG_VOICE.getCode().byteValue())
                .build()));
        // 取材记录
        List<RoutineSingleSampleVo> routineSingleSampleVoList = singleSampleService.selectList(RoutineSingleSampleSearchVo.builder()
                .qcId(routineQcVo.getId())
                .build());
        for (RoutineSingleSampleVo singleSampleVo : routineSingleSampleVoList){
            if (StringUtils.hasText(singleSampleVo.getNumber()) && singleSampleVo.getNumber().contains("-")){
                String[] numberArr = singleSampleVo.getNumber().split("-");
                singleSampleVo.setNumber(numberArr[1]);
            }
        }
        routineQcVo.setRoutineSingleVos(routineSingleSampleVoList);
        // 样本状态
        routineQcVo.setStepVo(stepService.selectOne(RoutineStepSearchVo.builder()
                        .conventionPathologyNumber(routineQcVo.getConventionPathologyNumber())
                        .build()));
        // 先获取所有的大样本信息
        List<RoutineSampleVo> routineSampleVos = sampleService.selectList(RoutineSampleSearchVo.builder().conventionPathologyNumber(nums).build());
        if (CollUtil.isEmpty(routineSampleVos)) {
            return routineQcVo;
        }
        // 病人信息
        RoutinePatientVo routinePatient = patientService.selectOne(RoutinePatientSearchVo.builder().conventionPathologyNumber(nums).build());
        RoutineQcPatientVo qcPatientVo = new RoutineQcPatientVo();
        BeanUtils.copyProperties(routinePatient, qcPatientVo);
        routineQcVo.setPatientVo(qcPatientVo);
        // 病理样本信息
        List<RoutineQcSampleVo> qcSampleVos = new ArrayList<>();
        for (RoutineSampleVo sampleVo: routineSampleVos) {
            RoutineQcSampleVo qcSampleVo = new RoutineQcSampleVo();
            BeanUtils.copyProperties(sampleVo, qcSampleVo);
            qcSampleVo.setZyh(routinePatient.getZyh());
            qcSampleVo.setBq(routinePatient.getBq());
            qcSampleVo.setCh(routinePatient.getCh());
            qcSampleVo.setFixedTime(sampleVo.getOffBodyTime());
            qcSampleVos.add(qcSampleVo);
        }
        routineQcVo.setQcSampleVos(qcSampleVos);
        Integer hisCount = stepRecordService.count(RoutineStepRecordSearchVo.builder()
                .step(RoutineHistoryEnum.QC.getCode().byteValue())
                .conventionPathologyNumber(nums)
                .build());
        if (hisCount < 1) {
            // 修改状态 + 增加状态记录
            String contetnt = "在实验室取材";
            stepService.updateStepByNums(nums, contetnt, RoutinePathologySampleStepEnum.QC.getCode().byteValue());
            stepRecordService.insert(RoutineStepRecord.builder()
                    .conventionPathologyNumber(nums)
                    .step(RoutinePathologySampleStepEnum.QC.getCode().byteValue())
                    .content(contetnt)
                    .build());
        }

        return routineQcVo;
    }

    @Transactional(rollbackFor = Exception.class, value = "localTransactionManager")
    @Override
    public void deleteById(Long id) {
        mapper.deleteByPrimaryKey(id);
        // 删除取材记录
        singleSampleService.deleteByCondition(RoutineSingleSampleSearchVo.builder().qcId(id).build());
        // 删除照片、录音
        fileService.deleteByCondition(FileSearchVo.builder().dataId(id).build());
    }

    @Override
    public void deleteByIdList(List<Long> idList) {
        if (CollectionUtil.isEmpty(idList)) {
            return;
        }
        mapper.deleteByIdList(idList);
    }

    @Override
    public Long insert(RoutineQc routineQc) {
        Date now = new Date();
        routineQc.setCreateTime(now);
        routineQc.setUpdateTime(now);
        return mapper.insert(routineQc) > 0 ? routineQc.getId() : 0L;
    }

    @Override
    public Long insertSelective(RoutineQc routineQc) {
        Date now = new Date();
        routineQc.setCreateTime(now);
        routineQc.setUpdateTime(now);
        return mapper.insertSelective(routineQc) > 0 ? routineQc.getId() : 0L;
    }

    @Override
    public boolean update(RoutineQc routineQc) {
        Date now = new Date();
        routineQc.setUpdateTime(now);
        return mapper.updateByPrimaryKey(routineQc) != 0;
    }

    @Override
    public boolean updateByPrimaryKeySelective(RoutineQc record) {
        Date now = new Date();
        record.setUpdateTime(now);
        return mapper.updateByPrimaryKeySelective(record) != 0;
    }

    @Transactional(rollbackFor = Exception.class, value = "localTransactionManager")
    @Override
    public boolean save(RoutineQcSaveOrUpdateVo saveOrUpdateVo) {
        // 查询是否有相同病理号信息
        Integer count = this.count(RoutineQcSearchVo.builder().conventionPathologyNumber(saveOrUpdateVo.getConventionPathologyNumber()).build());
        AssertUtil.check(count > 0, "已存在相同病理号信息");
        RoutineQc routineQc = new RoutineQc();
        BeanUtils.copyProperties(saveOrUpdateVo, routineQc);
        Long insert = this.insert(routineQc);
        // 保存照片、录音
        fileService.insertBatch(saveOrUpdateVo.getPhotoLists(), FileTypeEnum.QC_BIG_PHOTO.getCode().byteValue(), insert);
        fileService.insertBatch(saveOrUpdateVo.getVoiceLists(), FileTypeEnum.QC_BIG_VOICE.getCode().byteValue(), insert);
        // 保存取材明细
        List<RoutineSingleSample> sampleList = new ArrayList<>();
        Date nowDate = new Date();
        for (RoutineSingleSampleSaveOrUpdateVo sample : saveOrUpdateVo.getRoutineSingleVos()) {
            RoutineSingleSample singleSample = new RoutineSingleSample();
            BeanUtils.copyProperties(sample, singleSample);
            singleSample.setQcId(insert);
            singleSample.setCreateTime(nowDate);
            singleSample.setUpdateTime(nowDate);
            sampleList.add(singleSample);
        }
        singleSampleService.insertBatch(sampleList);

        return insert != 0;
    }

    @Override
    public boolean modify(RoutineQcSaveOrUpdateVo saveOrUpdateVo) {
        RoutineQc old = this.selectById(saveOrUpdateVo.getId());
        AssertUtil.notNull(old, "此数据不存在或者已被删除");
        RoutineQc routineQc = new RoutineQc();
        BeanUtils.copyProperties(saveOrUpdateVo, routineQc);
        // 删除取材记录
        singleSampleService.deleteByCondition(RoutineSingleSampleSearchVo.builder().qcId(saveOrUpdateVo.getId()).build());
        // 删除照片、录音
        fileService.deleteByCondition(FileSearchVo.builder().dataId(saveOrUpdateVo.getId()).build());

        // 保存照片、录音
        fileService.insertBatch(saveOrUpdateVo.getPhotoLists(), FileTypeEnum.QC_BIG_PHOTO.getCode().byteValue(), saveOrUpdateVo.getId());
        fileService.insertBatch(saveOrUpdateVo.getVoiceLists(), FileTypeEnum.QC_BIG_VOICE.getCode().byteValue(), saveOrUpdateVo.getId());
        // 保存取材明细
        List<RoutineSingleSample> sampleList = new ArrayList<>();
        Date nowDate = new Date();
        for (RoutineSingleSampleSaveOrUpdateVo sample : saveOrUpdateVo.getRoutineSingleVos()) {
            RoutineSingleSample singleSample = new RoutineSingleSample();
            BeanUtils.copyProperties(sample, singleSample);
            if (StringUtils.hasText(singleSample.getNumber()) && !singleSample.getNumber().startsWith(old.getConventionPathologyNumber())){
                singleSample.setNumber(old.getConventionPathologyNumber() + "-" + singleSample.getNumber());
            }
            singleSample.setQcId(saveOrUpdateVo.getId());
            singleSample.setCreateTime(nowDate);
            singleSample.setUpdateTime(nowDate);
            sampleList.add(singleSample);
        }
        singleSampleService.insertBatch(sampleList);
        // 找到病理号对用的样本，修改取材医生和记录员
        List<RoutineSampleVo> routineSampleVos = sampleService.selectList(RoutineSampleSearchVo.builder()
                .conventionPathologyNumber(saveOrUpdateVo.getConventionPathologyNumber())
                .build());
        String takeName = saveOrUpdateVo.getTakeName();
        String jlyName = saveOrUpdateVo.getJlyName();
        String name = CurrentUserHolder.getUser().getName();
        for (RoutineSampleVo sampleVo : routineSampleVos) {
            RoutineSample sample = new RoutineSample();
            BeanUtils.copyProperties(sampleVo, sample);
            sample.setQcDoctor(takeName);
            sample.setWriteName(jlyName);
            sampleService.updateByPrimaryKeySelective(sample);
        }

        return this.update(routineQc);
    }

    @Override
    public RoutineQcVo selectOne(RoutineQcSearchVo routineQcSearchVo) {
        return mapper.selectOne(routineQcSearchVo);
     }

    @Override
    public Integer count(RoutineQcSearchVo routineQcSearchVo) {
        return mapper.count(routineQcSearchVo);
    }

    @Override
    public List<RoutineQcVo> selectList(RoutineQcSearchVo routineQcSearchVo) {
        return mapper.selectList(routineQcSearchVo);
    }

    @Override
    public List<RoutineQcPathologyVo> selectListPathology(RoutineQcPathologySearchVo routineQcSearchVo) {
        List<RoutineQcPathologyVo> routineQcPathologyVos = mapper.selectPatholoyList(routineQcSearchVo);
        for (RoutineQcPathologyVo vo : routineQcPathologyVos) {
            RoutinePatient patient1 = patientService.selectById(vo.getPatientId());
            vo.setWeatherSzFast((byte)(Objects.isNull(patient1.getConnectId()) ? 0 : 1));
        }
        return routineQcPathologyVos;
    }

    @Override
    public Page<RoutineQcVo> selectPage(RoutineQcSearchVo routineQcSearchVo) {
        AssertUtil.check(Objects.isNull(routineQcSearchVo.getPageNum()) || Objects.isNull(routineQcSearchVo.getPageSize()), "分页参数不能为空");
        //先直接查总数
        int count = count(routineQcSearchVo);
        //分页
        Page<RoutineQcVo> page = new Page<>(true, count, routineQcSearchVo.getPageNum(), routineQcSearchVo.getPageSize());
        routineQcSearchVo.setStartIndex(page.getStartIndex());
        page.setPage(true);
        page.setTotalCount(count);
        List<RoutineQcVo> responseVos = this.selectList(routineQcSearchVo);
        page.setData(responseVos);
        return page;
    }

    @Override
    public Page<RoutineQcPathologyVo> selectPagePathology(RoutineQcPathologySearchVo routineQcSearchVo) {
        AssertUtil.check(Objects.isNull(routineQcSearchVo.getPageNum()) || Objects.isNull(routineQcSearchVo.getPageSize()), "分页参数不能为空");
        //先直接查总数
        int count = countPatholoy(routineQcSearchVo);
        //分页
        Page<RoutineQcPathologyVo> page = new Page<>(true, count, routineQcSearchVo.getPageNum(), routineQcSearchVo.getPageSize());
        routineQcSearchVo.setStartIndex(page.getStartIndex());
        page.setPage(true);
        page.setTotalCount(count);
        List<RoutineQcPathologyVo> responseVos = this.selectListPathology(routineQcSearchVo);
        page.setData(responseVos);
        return page;
    }

    @Override
    public boolean insertBatch(List<RoutineQc> entities) {
        return CollectionUtil.isNotEmpty(entities) && mapper.insertBatch(entities) > 0;
    }

    @Override
    public void deleteByCondition(RoutineQcSearchVo routineQcSearchVo) {
        //慎重用此方法！！
        mapper.deleteByCondition(routineQcSearchVo);
    }

    @Override
    public int countPatholoy(RoutineQcPathologySearchVo routineQcSearchVo) {
        return mapper.countPatholoy(routineQcSearchVo);
    }

    @Override
    public int countPatholoyDay(String startTime) {
        return mapper.countPatholoyDay(startTime);
    }

    @Override
    public List<RoutineQcPathologyVo> selectPatholoyListDay(RoutineQcPathologySearchVo searchVo) {
        return mapper.selectPatholoyListDay(searchVo);
    }

    @Override
    public Page<RoutineQcPathologyVo> selectPageDay(PageVo pageVo) {
        RoutineQcPathologySearchVo searchVo = new RoutineQcPathologySearchVo();
        BeanUtils.copyProperties(pageVo, searchVo);
        AssertUtil.check(Objects.isNull(searchVo.getPageNum()) || Objects.isNull(searchVo.getPageSize()), "分页参数不能为空");
        // 获取今天的开始时间
        DateTime dateTime = DateUtil.beginOfDay(new Date());
        String startTime = DateUtil.formatDateTime(dateTime);
        searchVo.setStartTime(startTime);
        //先直接查总数
        int count = countPatholoyDay(startTime);
        //分页
        Page<RoutineQcPathologyVo> page = new Page<>(true, count, searchVo.getPageNum(), searchVo.getPageSize());
        searchVo.setStartIndex(page.getStartIndex());
        page.setPage(true);
        page.setTotalCount(count);
        List<RoutineQcPathologyVo> responseVos = this.selectPatholoyListDay(searchVo);
        page.setData(responseVos);
        return page;
    }
    
}